﻿using System;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text;

namespace GLLog.Net
{
    /// <summary>
    /// 客户端与服务器之间的会话类
    /// </summary>
    public class Session : ICloneable
    {
        #region 字段
        /// <summary>
        /// 会话ID
        /// </summary>
        private SessionId _id;
        /// <summary>
        /// 接收数据缓冲区
        /// </summary>
        private byte[] _recvDataBuffer;
        /// <summary>
        /// 客户端的Socket
        /// </summary>
        private Socket _cliSock;
        #endregion

        #region 属性
        /// <summary>
        /// 返回会话的ID
        /// </summary>
        public SessionId ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }
        /// <summary>
        /// 接收数据缓冲区 
        /// </summary>
        public byte[] RecvDataBuffer
        {
            get
            {
                return _recvDataBuffer;
            }
            set
            {
                _recvDataBuffer = value;
            }
        }
        /// <summary>
        /// 获得与客户端会话关联的Socket对象
        /// </summary>
        public Socket ClientSocket
        {
            get
            {
                return _cliSock;

            }
        }
        #endregion

        #region 方法
        /// <summary>
        /// 使用Socket对象的Handle值作为HashCode,它具有良好的线性特征.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (int)_cliSock.Handle;
        }

        /// <summary>
        /// 返回两个Session是否代表同一个客户端
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            Session rightObj = (Session)obj;
            return (int)_cliSock.Handle == (int)rightObj.ClientSocket.Handle;
        }

        /// <summary>
        /// 重载ToString()方法,返回Session对象的特征
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string result = string.Format("Session:{0},IP:{1}",
             _id, _cliSock.RemoteEndPoint.ToString());

            //result.C
            return result;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cliSock">会话使用的Socket连接</param>
        public Session(Socket cliSock)
        {
            _cliSock = cliSock;
            _id = new SessionId((int)cliSock.Handle);
        }

        /// <summary>
        /// 关闭会话
        /// </summary>
        public void Close()
        {
            //关闭数据的接受和发送
            _cliSock.Shutdown(SocketShutdown.Both);
            //关闭连接，可复用
            _cliSock.Disconnect(true);
            //清理资源
            _cliSock.Close();
        }

        #endregion

        #region ICloneable 成员
        object System.ICloneable.Clone()
        {
            Session newSession = new Session(_cliSock);
            return newSession;
        }
        #endregion
    }
}